package com.ermax.aircond.manage.dao;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.manage.domain.ScheduleTerm;
import com.ermax.aircond.util.dao.AbstractHibernateDao;

@Repository("scheduleTermDao")
public class ScheduleTermDao extends AbstractHibernateDao<ScheduleTerm> implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static final Logger logger = Logger.getLogger(ScheduleTermDao.class);

	public ScheduleTermDao() {
		setClazz(ScheduleTerm.class);
	}
	
	public List<ScheduleTerm> findScheduleTermByMachine(Machine machine){
		Criteria criteria = this.getCurrentSession().createCriteria(ScheduleTerm.class);		
		
		if(isNotNull(machine)){
			criteria.add(Restrictions.eq("machine", machine));
		}
		
		criteria.addOrder(Order.asc("nid"));
		criteria.addOrder(Order.asc("scheduleHour"));
		criteria.addOrder(Order.asc("scheduleMin"));
		
		
		@SuppressWarnings("unchecked")
		List<ScheduleTerm> results = criteria.list();
		return results;
	}
	
	public List<ScheduleTerm> findScheduleTermByNid(short nid){
		Criteria criteria = this.getCurrentSession().createCriteria(ScheduleTerm.class);		
				
		criteria.add(Restrictions.eq("nid", nid));
				
		criteria.addOrder(Order.asc("nid"));
		criteria.addOrder(Order.asc("scheduleHour"));
		criteria.addOrder(Order.asc("scheduleMin"));
		
		
		@SuppressWarnings("unchecked")
		List<ScheduleTerm> results = criteria.list();
		return results;
	}
	
	public List<ScheduleTerm> getScheduleToRun() {
		
		logger.debug("Get schedule within range!");
		
		Query query = this.getCurrentSession().createSQLQuery("select schedule_id, nid, cmd from dbo.SCHEDULE_TERM where CONVERT (date, SYSDATETIME()) > CONVERT (date, lastExecuteTime) and DATEPART(HOUR, sysdatetime()) = DATEPART(HOUR, convert(datetime, scheduleHour + ':' + scheduleMin + ':' + '00', 8)) and DATEPART(MINUTE, sysdatetime()) - DATEPART(MINUTE, convert(datetime, scheduleHour + ':' + scheduleMin + ':' + '00', 8)) <= 15 and ( (DATEPART(WEEKDAY, sysdatetime()) = 1 and execSun = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 2 and execMon = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 3 and execThu = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 4 and execWed = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 5 and execThu = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 6 and execFri = 'Y') or (DATEPART(WEEKDAY, sysdatetime()) = 7 and execSat= 'Y')) ");

		@SuppressWarnings("unchecked")
		List<Object[]> recordList = query.list();
		
		if (null != recordList && recordList.size() > 0) {
		
			List<ScheduleTerm> scheduleTermList = new ArrayList<ScheduleTerm>();
			for (Object[] fields : recordList) {
				ScheduleTerm scheduleTerm = new ScheduleTerm();
				scheduleTerm.setId(((BigDecimal)fields[0]).longValue());
				scheduleTerm.setNid((Short) fields[1]);
				scheduleTerm.setCmd(fields[2].toString());
				scheduleTermList.add(scheduleTerm);
			}
			
			return scheduleTermList;
		} else {		
			return null;
		}
		
	}
	
	public void updateScheduleExecutedTime(ScheduleTerm scheduleTerm) {
		
		logger.debug("Update Schedule Last Executed Time!");
		
		Query q = this.getCurrentSession().createSQLQuery("update dbo.SCHEDULE_TERM set lastExecuteTime = SYSDATETIME() where SCHEDULE_ID = :sid");
		q.setParameter("sid", scheduleTerm.getId());
		
		q.executeUpdate();
	}

}
